#include "mainwindow.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPushButton>
#include <QSlider>
#include <QFileDialog>
#include <stdlib.h>
#include <fcntl.h>
#include <iplqimage.h>
#include <QDebug>
#include <QListWidgetItem>
#include <QStringList>

#include "timecodechecker.h"
#include "videomaker.h"

MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    initScene();
    initWindow();
    gii = NULL;

//    QStringList a;
//    a << "33" << "3" << "ssfsdkf" << "dfajd3lkj";
//    qDebug() << a.lastIndexOf("4");   //returns -1;
//    qDebug() << a.lastIndexOf("3");   //returns 0;
}

MainWindow::~MainWindow()
{
    
}

void MainWindow::initScene()
{
    captureScene = new QGraphicsScene;
    captureView = new QGraphicsView;
    captureView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    captureView->setDragMode(QGraphicsView::RubberBandDrag);
    captureView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    captureView->setScene(captureScene);
//    captureView->resize(800, 600);
}

void MainWindow::initWindow()
{
//    btnLoad = new QPushButton(tr("Load raw file"));     /* old load button */
    btnCheckTC = new QPushButton(tr("Check TimeCode"));     /* Added by Lin */
    sliderFrames = new QSlider(Qt::Horizontal);
    ledGoFrame = new QLineEdit(tr("0"));
    ledGoFrame->setFixedWidth(30);
    btnGoFrame = new QPushButton(tr("Go"));
    btnGoFrame->setFixedWidth(30);
    saveImagesPath = new QLineEdit(tr("Choose a folder to save Images"));
    btnSelectFolder = new QPushButton(tr("..."));
    sliderFrames->setTickPosition(QSlider::TicksBelow);
    QHBoxLayout *sliderHLayout = new QHBoxLayout;

    sceneVLayout = new QVBoxLayout;
//    sceneVLayout->addWidget(btnLoad);     /* old load button */

    sceneVLayout->addWidget(captureView);
    sceneVLayout->addLayout(sliderHLayout);
    sliderHLayout->addWidget(sliderFrames);
    sliderHLayout->addWidget(ledGoFrame);
    sliderHLayout->addWidget(btnGoFrame);

    filesListStr = new QStringList; /* Added by Lin */
    this->setMinimumSize(800, 600);

    cbxAllFrames = new QCheckBox(tr("All Frames"));
    cbxAllFrames->setChecked(true);
    cbxAllVideos = new QCheckBox(tr("All Files"));
    QLabel *lebStartF = new QLabel(tr("Start Frame"));
    QLabel *lebFTotal = new QLabel(tr("Frames Total"));
    ledStartFrame = new QLineEdit;
    ledStartFrame->setEnabled(false);
    ledFrameNo = new QLineEdit;
    ledFrameNo->setEnabled(false);
    btnSaveImages = new QPushButton(tr("Save Images"));

    btnSave2StdRaw = new QPushButton(tr("Save to standard raw file"));
    btnSave2StdRaw->setEnabled(false);

    QHBoxLayout *frameNoHLayout  = new QHBoxLayout;
    QLabel *msg1 = new QLabel(tr("Total frames:"));
    QLabel *msg2 = new QLabel(tr("  First frame:"));
    QLabel *msg3 = new QLabel(tr("  Last frame:"));
    lbTotalFrames = new QLabel;
    lbFirstFrame = new QLabel;
    lbLastFrame = new QLabel;
    frameNoHLayout->addWidget(msg1);
    frameNoHLayout->addWidget(lbTotalFrames);
    frameNoHLayout->addWidget(msg2);
    frameNoHLayout->addWidget(lbFirstFrame);
    frameNoHLayout->addWidget(msg3);
    frameNoHLayout->addWidget(lbLastFrame);

    QHBoxLayout *saveHLayout = new QHBoxLayout;
    saveHLayout->addWidget(cbxAllFrames);
    saveHLayout->addWidget(cbxAllVideos);
    saveHLayout->addWidget(lebStartF);
    saveHLayout->addWidget(ledStartFrame);
    saveHLayout->addWidget(lebFTotal);
    saveHLayout->addWidget(ledFrameNo);

    sceneVLayout->addLayout(frameNoHLayout);

    sceneVLayout->addWidget(btnCheckTC);    /* Added by Lin */
    pathHLayout = new QHBoxLayout;
    pathHLayout->addWidget(saveImagesPath);
    pathHLayout->addWidget(btnSelectFolder);
    sceneVLayout->addLayout(pathHLayout);
    sceneVLayout->addLayout(saveHLayout);
    sceneVLayout->addWidget(btnSaveImages);

    saveImagesPath->setEnabled(false);
    btnSelectFolder->setFixedWidth(30);
    btnSaveImages->setEnabled(false);
    sceneVLayout->addWidget(btnSave2StdRaw);

    btnCreateVideo = new QPushButton(tr("Create Video"));
    sceneVLayout->addWidget(btnCreateVideo);

    lswVideoList = new QListWidget;
    lswVideoList->setFixedWidth(200);

    listBtnHLayout = new QHBoxLayout;
    btnAddVideo = new QPushButton(tr("Add"));
    btnRemoveVideo = new QPushButton(tr("Remove"));
    listBtnHLayout->addWidget(btnAddVideo);
    listBtnHLayout->addWidget(btnRemoveVideo);

    listVLayout = new QVBoxLayout;
    listVLayout->addWidget(lswVideoList);
    listVLayout->addLayout(listBtnHLayout);

    mainHLayout = new QHBoxLayout;
    mainHLayout->addLayout(listVLayout);
    mainHLayout->addLayout(sceneVLayout);
    this->setLayout(mainHLayout);

//    connect(btnLoad,SIGNAL(clicked()),SLOT(onLoadClicked()));     /* old load button */
    connect(btnAddVideo, SIGNAL(clicked()), SLOT(onAddVideoClicked()));
    connect(btnRemoveVideo, SIGNAL(clicked()), SLOT(onRemoveVideoClicked()));
    connect(btnCheckTC, SIGNAL(clicked()), SLOT(onCheckTCClicked()));    /* Added by Lin */
    connect(btnSelectFolder, SIGNAL(clicked()), SLOT(onSelectFolderClicked()));
    connect(btnSaveImages, SIGNAL(clicked()), SLOT(onSaveImagesClicked()));
    connect(btnSave2StdRaw, SIGNAL(clicked()), SLOT(onSave2StdRawClicked()));
    connect(cbxAllFrames, SIGNAL(toggled(bool)), SLOT(onAllFramesToggled(bool)));
    connect(btnCreateVideo, SIGNAL(clicked()), SLOT(onCreateVideoClicked()));
//    qDebug() << "Test.";
}

void MainWindow::onAddVideoClicked()
{
    *filesListStr = QFileDialog::getOpenFileNames(this, tr("Select Captured File"), tr("/ssd/tmp"));
    if (!filesListStr->isEmpty()) {
        for (int i=0; i<filesListStr->count(); i++)
            lswVideoList->addItem(filesListStr->at(i));
        //    qDebug() << "Test.";
        lswVideoList->setCurrentRow(0);
        onLoadVideo(lswVideoList->currentItem()->text());
        connect(lswVideoList, SIGNAL(currentTextChanged(QString)), this, SLOT(onLoadVideo(QString)));
    }
}

void MainWindow::onRemoveVideoClicked()
{
    if (lswVideoList->count() > 1)
    {
        int cur = lswVideoList->currentRow();
        if (cur <= (lswVideoList->count()-1))
        {
            lswVideoList->setCurrentRow(cur+1);
        }
        else
        {
            lswVideoList->setCurrentRow(cur-1);
        }
        QListWidgetItem *item = lswVideoList->takeItem(cur);
        lswVideoList->removeItemWidget(item);
        delete item;
    } else if (lswVideoList->count() == 1)
    {
        disconnect(lswVideoList, SIGNAL(currentTextChanged(QString)), this, SLOT(onLoadVideo(QString)));
        QListWidgetItem *item = lswVideoList->takeItem(0);
        lswVideoList->removeItemWidget(item);
        delete item;
    }
}

void MainWindow::onLoadVideo(QString videoFile)
{
//    QStringList filesListStr;
//    if (gii != null)
//    {
//    }
    if (!videoFile.isEmpty())
    {
        gii = new GraphicsImageItem(&videoFile,1920*2,1080);
        captureScene->clear();
        if(gii)
        {
            captureScene->addItem(gii);
        }
        this->sliderFrames->setMinimum(0);
        this->sliderFrames->setMaximum(gii->FrameCount()-1);
        lbTotalFrames->clear();
        lbTotalFrames->setText(tr("%1").arg(gii->FrameCount()));
        lbFirstFrame->clear();

        connect(this->sliderFrames,SIGNAL(valueChanged(int)),SLOT(onFrameSliderUpdated(int)));
        connect(this,SIGNAL(updateFrame(off64_t)),gii,SLOT(onTimeStampUpdated(off64_t)));

        btnSaveImages->setEnabled(true);
        btnSave2StdRaw->setEnabled(true);
    }
//    QString str("/home/haoliu/testhdraw.raw");
//    GraphicsImageItem *gii = new GraphicsImageItem(&str,1920*2,1080);
//    captureScene->clear();
//    captureScene->addItem(gii);
}

void MainWindow::onFrameSliderUpdated(int value)
{
    off64_t value64 = value;
    ledStartFrame->setText(tr("%1").arg(value));
    emit updateFrame(value64);
}

//Added by Lin
void MainWindow::onCheckTCClicked()
{
    //todo
    if (lswVideoList->count() == 0) {
//        onLoadVideo();    /*old load button*/
    } else {
        TimecodeChecker *checker;
        QString str(lswVideoList->currentItem()->text());
        checker = new TimecodeChecker(str,1920*2,1080);
        checker->show();
    }
}

void MainWindow::onSaveImagesClicked()
{
    //todo
    if (saveImagesPath->toolTip().isEmpty()) {
        onSelectFolderClicked();
    }
    if (!cbxAllVideos->isChecked()) {
        if (cbxAllFrames->isChecked())
            gii->saveFrames(saveImagesPath->toolTip());
        else
        {
            int start = ledStartFrame->text().toInt();
            int number = ledFrameNo->text().toInt();
            gii->saveFrames(saveImagesPath->toolTip(), start, number);
        }
    } else {
        for (int i=0; i<lswVideoList->count(); i++)
        {
            lswVideoList->setCurrentRow(i);
            if (cbxAllFrames->isChecked())
                gii->saveFrames(saveImagesPath->toolTip());
            else
            {
                int start = ledStartFrame->text().toInt();
                int number = ledFrameNo->text().toInt();
                gii->saveFrames(saveImagesPath->toolTip(), start, number);
            }
        }
    }
}

void MainWindow::onSelectFolderClicked()
{
    QString path = QFileDialog::getExistingDirectory(this, tr("Select a folder to save images."), tr("."));
    if (path.length() != 0) {
        saveImagesPath->setText(path);
        saveImagesPath->setToolTip(path);
    }
}

void MainWindow::onSave2StdRawClicked()
{
    //todo
    
    if (!ledFrameNo->text().isEmpty())
    {
        QString fullPath = QFileDialog::getSaveFileName(this, tr("Select a directory"), "/ssd/tmp");
        if (!fullPath.isEmpty()) {
            int start = ledStartFrame->text().toInt();
            QByteArray file = fullPath.toLatin1();
            int count = ledFrameNo->text().toInt();
            int outputFile = open(file.data(), O_WRONLY|O_CREAT|O_TRUNC, 0664);

            IplImage* tmp;
            for (int i=0; i<count; i++) {
                sliderFrames->setValue(start+i);
                tmp  = gii->getImageData();
                write(outputFile, tmp->imageData, ROWBYTES*IMGHEIGHT);
            }
        }
    }
}

void MainWindow::onAllFramesToggled(bool flag)
{
    ledStartFrame->setEnabled(!flag);
    ledFrameNo->setEnabled(!flag);
}

void MainWindow::onCreateVideoClicked()
{
    //
    VideoMaker *vMaker;
    vMaker = new VideoMaker;
    vMaker->show();
}

// Code above was added by Lin

